﻿/* ********************************************************************************
 * 名称：MngrBaseInfo_DomainService
 * 描述：系统用户表  领域服务接口实现类（本类通过CodeSmith软件生成生成）
 * 创建人：HFL
 * 创建日期：2020-06-01 17:48:55
 * 修改人：
 * 修改日期：
 * *******************************************************************************/
using WPay.Domain.Base;
using WPay.Domain.Model.DTOs;
using WPay.Domain.Model.Entities;
using WPay.Domain.MainModule.Interface.DomainServices;
using WPay.Domain.MainModule.Interface.RepositoryServices;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Model.DTO.Manager;
using WPay.Infrastructure.Unity;
using Utility.Enums;
using System.Linq;
using Utility;
using AutoMapper;
using Microsoft.AspNetCore.Http;



namespace WPay.Domain.MainModule
{
    /// <summary>
    /// 系统用户表 领域服务接口实现类
    /// </summary>
    public class MngrBaseInfo_DomainService : IMngrBaseInfo_DomainService
    {

        /// <summary>
        /// 系统用户表 领域服务接口
        /// </summary>
        public IMngrBaseInfo_RepositoryService _mngrBaseInfo_RepositoryService;
        public IMngrRole_DomainService _mngrRole_DomainService;
        public Hashtable hashtable = new Hashtable();
        public ISysRoleAction_RepositoryService _RoleAction_RepositoryService;
        public ISysModule_RepositoryService _sysModule_RepositoryService;
        public IEfCore_RepositoryService _efCore_RepositoryService;
        public IMngrLog_DomainService _mngrLog_DomainService;
        /// <summary>
        /// 带参构造，用于IOC
        /// </summary>
        public MngrBaseInfo_DomainService(IMngrBaseInfo_RepositoryService mngrBaseInfo_RepositoryService,
            IMngrRole_DomainService mngrRole_DomainService, ISysRoleAction_RepositoryService RoleAction_RepositoryService,
            ISysModule_RepositoryService sysModule_RepositoryService, IEfCore_RepositoryService efCore_RepositoryService,
            IMngrLog_DomainService mngrLog_DomainService)
        {
            _mngrBaseInfo_RepositoryService = mngrBaseInfo_RepositoryService;
            _mngrRole_DomainService = mngrRole_DomainService;
            _RoleAction_RepositoryService = RoleAction_RepositoryService;
            _sysModule_RepositoryService = sysModule_RepositoryService;
            _efCore_RepositoryService = efCore_RepositoryService;
            _mngrLog_DomainService = mngrLog_DomainService;
        }
        #region 由软件生成，禁止修改，若需要扩展，请在下方进行扩展

        /// <summary>
        /// 根据主键获取系统用户表资料信息
        /// </summary>
        /// <param name="_iD"></param>
        /// <returns>返回单个系统用户表数据实体</returns>
        public MngrBaseInfo Get(string _iD)
        {
            return this._mngrBaseInfo_RepositoryService.Get(_iD);
        }

        /// <summary>
        /// 获取所有记录
        /// </summary>
        /// <param name="_cpnID">企业代码</param>
        /// <returns>返回系统用户表数据集合</returns>
        public List<MngrBaseInfo> GetAll(string _cpnID)
        {
            return this._mngrBaseInfo_RepositoryService.GetAll(_cpnID);
        }

        /// <summary>
        /// 获取所有记录
        /// </summary>
        /// <param name="_param">查询条件字典，其中key必须使用字段名</param>
        /// <returns>返回系统用户表数据集合</returns>
        public List<MngrBaseInfo> GetAll(Hashtable _param)
        {
            return this._mngrBaseInfo_RepositoryService.GetAll(_param);
        }

        /// <summary>
        /// 按照分页条件查询数据集
        /// </summary>
        /// <param name="_param">查询条件字典，其中key必须使用字段名</param>
        /// <param name="_pageIndex">查询页码，从1开始，必传</param>
        /// <param name="_pageSize">每页查询数据条数，必传</param>
        /// <param name="_sort">排序列名，若要降序请用列名+" DESC"，必传</param>
        /// <param name="_pageCount">返回总页码数</param>
        /// <param name="_dataCount">返回总数据条数</param>
        /// <returns>返回系统用户表数据集合</returns>
        public List<MngrBaseInfo> GetByPage(Hashtable _param, int _pageIndex, int _pageSize, string _sort, out int _pageCount, out int _dataCount)
        {
            return this._mngrBaseInfo_RepositoryService.GetByPage(_param, _pageIndex, _pageSize, _sort, out _pageCount, out _dataCount);
        }

        /// <summary>
        /// 插入系统用户表数据
        /// </summary>
        /// <param name="_mngrBaseInfo">需要插入的系统用户表数据实体</param>
        /// <returns>返回影响数据行数</returns>
        public int Add(MngrBaseInfo _mngrBaseInfo)
        {
            return this._mngrBaseInfo_RepositoryService.Add(_mngrBaseInfo);
        }

        /// <summary>
        /// 批量插入系统用户表数据
        /// </summary>
        /// <param name="_mngrBaseInfoList">需要插入的系统用户表数据集合</param>
        /// <returns>返回影响数据行数</returns>
        public int Add(List<MngrBaseInfo> _mngrBaseInfoList)
        {
            return this._mngrBaseInfo_RepositoryService.Add(_mngrBaseInfoList);
        }

        /// <summary>
        /// 根据主键更新系统用户表数据
        /// </summary>
        /// <param name="_mngrBaseInfo">需要更新的系统用户表数据实体</param>
        /// <returns>返回影响数据行数</returns>
        public int Update(MngrBaseInfo _mngrBaseInfo)
        {
            return this._mngrBaseInfo_RepositoryService.Update(_mngrBaseInfo);
        }

        /// <summary>
        /// 根据主键更新系统用户表指定字段
        /// </summary>
        /// <param name="_mngrBaseInfo">需要更新的系统用户表数据实体</param>
        /// <param name="_updateProNames">需要更新的字段名</param>
        /// <returns>返回影响数据行数</returns>
        public int Update(MngrBaseInfo _mngrBaseInfo, params string[] _updateProNames)
        {
            return this._mngrBaseInfo_RepositoryService.Update(_mngrBaseInfo, _updateProNames);
        }



        #endregion

        /*业务扩展代码*/
        #region 业务扩展代码

        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="sLoginName"></param>
        /// <param name="sPassWord"></param>
        /// <returns></returns>
        public LoginUserDTO Login(string sLoginName, string sPassWord, string type = "0")
        {
            var data = new LoginUserDTO();
            if (string.IsNullOrEmpty(sLoginName) || string.IsNullOrEmpty(sPassWord))
            {
                throw new UNException("请输入账户和密码");
            }
            var passWord = MD5Helper.GetMD5(sPassWord);
            var user = _efCore_RepositoryService.GetByCondition<MngrBaseInfo>(new DirectSpecification<MngrBaseInfo>(x => x.LoginName == sLoginName && x.PassWord == passWord&&!x.IsDeleted));
            if (null == user)
            {
                throw new UNException("账号或密码错误,请重试!");
            }
            else
            {
                if (user.State == Enum_ManagerUserState.Locked)
                {
                    throw new UNException("该用户已被锁定!");
                }
                else
                {
                    hashtable = new Hashtable();
                    hashtable.Add("IsDeleted", 0);
                    hashtable.Add("MemberId", $"{user.ID}");
                    var roles = _efCore_RepositoryService.GetMany<MngrRole>(new DirectSpecification<MngrRole>(x => !x.IsDeleted && x.MemberId == user.ID)).ToList();
                    data = BindDTO(user, roles);
                   
                    //记录登录时间和IP
                    user.LastLoginIP = user.ThisLoginIP;
                    user.LastLoginTime = user.ThisLoginTime;
                    user.ThisLoginIP = IPHelper.getIPAddr();
                    user.ThisLoginTime = DateTime.Now;
                    user.LoginNumber = (user.LoginNumber ?? 0) + 1;
                    var dbcpn = _efCore_RepositoryService.GetByCondition(new DirectSpecification<Cpn>(x => x.CpnID == user.CpnId));
                    if (dbcpn != null)
                    {
                        data.CpnName = dbcpn.CpnID == "system" ? "西联" : dbcpn.Name;
                    }
                    _mngrBaseInfo_RepositoryService.Update(user, "LastLoginTime", "LastLoginIP", "ThisLoginTime", "ThisLoginIP", "LoginNumber");
                    data.CpnId = user.CpnId;
                    var httpcontxt = MvcContext.GetContext();
                    //获取签名
                    var jwt = RayPIToken.IssueJWT(new TokenModel()
                    {
                        Origin = httpcontxt.Request.Headers["Origin"],
                        Uid = data.ID,
                        Uname = data.LoginName,
                        UNickname = data.NickName,
                        Sub = "Admin",
                        StartTime = DateTime.Now,
                        UserJson = Newtonsoft.Json.JsonConvert.SerializeObject(data)
                    }, TimeSpan.FromDays(1), TimeSpan.FromDays(1)); ;
                    data.jwt = jwt;

                }
            }
            if (string.IsNullOrEmpty(data.Menu))
            {
                throw new UNException("当前账户未包含任何角色权限,请联系管理员进行处理后登陆");
            }
            _efCore_RepositoryService.Add(new MngrLog()
            {
                ID = Guid.NewGuid().ToString(),
                UId = data?.ID,
                CreateTime = DateTime.Now,
                Titles = "系统登录",
                Contents = $"用户{data.LoginName}登录系统",
                IpAddress = IPHelper.getIPAddr()
            });
            _efCore_RepositoryService.SaveChanges();
            return data;

        }
     

        /// <summary>
        /// 登陆数据绑定
        /// </summary>
        /// <param name="user"></param>
        /// <param name="Roles"></param>
        /// <returns></returns>
        public virtual LoginUserDTO BindDTO(MngrBaseInfo user, List<MngrRole> Roles)
        {


            var data = new LoginUserDTO()
            {
                ID = user.ID,
                LoginName = user.LoginName,
                NickName = user.NickName,
                LoginIp = user.LastLoginIP,
                IsDeleted = user.IsDeleted,
                State = user.State,
                PassWord = user.PassWord
            };
            //automapper初始化一次dto

            data.LoginIp = IPHelper.getIPAddr();
            data.UserActionList = new List<RoleActionDTO>();
            var allRoleActions = new List<SysRoleAction>();
            var roleids = Roles.Select(x => x.RoleId.ToString());
            var mngroleRoleActions = _RoleAction_RepositoryService.GetSysRoleActions(roleids);
            Roles.ForEach(x =>
            {
                if (mngroleRoleActions.Any(y => y.RoleID == x.RoleId))
                {
                    allRoleActions.AddRange(mngroleRoleActions.Where(y => y.RoleID == x.RoleId).ToList());
                }
            });
            //if (allRoleActions.Any())
            //{
            //    allRoleActions = allRoleActions.GroupBy(x => x.ModuleID).Select(x => new SysRoleAction() { ID = Guid.NewGuid().ToString(), ModuleID = x.Key, Weight = x.Max(y => y.Weight) }).ToList();
            //}
            //将登录者的角色存入dto
            allRoleActions.ForEach(x =>
            {
                var dto = new RoleActionDTO()
                {
                    RoleID = x.RoleID,
                    ModuleID = x.ModuleID,
                    Weight = x.Weight
                };
                data.UserActionList.Add(dto);
            });
            var Weight = 0;
            var modultaction = _sysModule_RepositoryService.GetModultAction();
            modultaction.ForEach(
                x =>
                {
                    var url = string.IsNullOrEmpty(x.ActionUrl) ? new string[0] : x.ActionUrl.Split('/');
                    var dto = new RoleAction_ModuleDTO
                    {
                        controllerName = url.Length > 1 ? url[1].ToLower() : "",
                        actionName = url.Length > 2 ? url[2].ToLower() : "",
                    };
                    data.UserActionList.ForEach(y =>
                    {
                        y.ModuleDtos = y.ModuleDtos ?? new List<RoleAction_ModuleDTO>();
                        if (y.ModuleID == x.ModuleID)
                        {
                            Weight = y.Weight;
                            if ((Weight & x.Weight) == x.Weight)
                            {
                                y.ModuleDtos.Add(new RoleAction_ModuleDTO()
                                {
                                    ModuleID = x.ModuleID,
                                    controllerName = url.Length > 1 ? url[1].ToLower() : "",
                                    actionName = url.Length > 2 ? url[2].ToLower() : "",
                                    FatherModuleName = x.FatherModuleName,
                                    ModuleName = x.ModuleName,
                                    ModuleActionName = x.ActionName,
                                    ShowEnum = x.ShowEnum,
                                    ActionCls = x.ActionCls,
                                    ActionFun = x.ActionFun,
                                    OrderId = x.OrderID,
                                    ActionUrl = x.ActionUrl
                                });
                            }
                        }
                    });
                });
            if (data.UserActionList.Any())
            {
                //根据已有的权限做菜单绑定
                data.Menu = _sysModule_RepositoryService.GetLoginRoleMenu(data);
            }
            return data;
        }
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="model"></param>
        /// <param name="httpRequest"></param>
        /// <returns></returns>
        public LoginUserDTO AddMangerBaseInfo(MngrBaseInfo model, HttpRequest httpRequest)
        {
            var data = new LoginUserDTO();
            var Roles = Newtonsoft.Json.JsonConvert.DeserializeObject<List<MngrRole>>(httpRequest.Form["roles"]);
            var type = Convert.ToInt32(httpRequest.Form["typ"]);
            if (string.IsNullOrEmpty(model.ID))//Add
            {
                var oldbase = _efCore_RepositoryService.GetByCondition(new DirectSpecification<MngrBaseInfo>(x => x.LoginName == model.LoginName && !x.IsDeleted));
                if (oldbase != null)
                {
                    throw new UNException("该登录名已经存在!");
                }
                if (string.IsNullOrEmpty(model.LoginName))
                {
                    throw new UNException("请输入登录名");
                }
                if (string.IsNullOrEmpty(model.NickName))
                {
                    throw new UNException("请输入昵称");
                }
                if (string.IsNullOrEmpty(model.PassWord))
                {
                    throw new UNException("请输入密码");
                }
                if (Roles == null)
                {
                    throw new UNException("至少选择一个角色");
                }

                model.ID = System.Guid.NewGuid().ToString();
                model.CreateTime = DateTime.Now;
                model.PassWord = MD5Helper.GetMD5(model.PassWord);
                foreach (MngrRole item in Roles)
                {
                    item.CreateTime = DateTime.Now;
                    item.ID = Guid.NewGuid().ToString();
                    item.MemberId = model.ID;
                }
                Add(model);
                _mngrLog_DomainService.AddMngrLog("新增用户", $"用户:{model.LoginName}被新增");
                _efCore_RepositoryService.AddBatch(Roles);
            }
            else//Editor
            {
                if (string.IsNullOrEmpty(model.NickName))
                {
                    throw new UNException("请输入昵称");
                }
                if (Roles == null)
                {
                    throw new UNException("至少选择一个角色");
                }
                if (model.PassWord.Length > 0 && model.PassWord.Length < 6 && type == 3)
                {
                    throw new UNException("最少输入6个字符");
                }
                var old = _efCore_RepositoryService.GetByCondition(new DirectSpecification<MngrBaseInfo>(x => x.ID == model.ID && !x.IsDeleted));
                old.NickName = model.NickName;
                old.LoginName = model.LoginName;
                //old.CpnId = model.CpnId;
                if (type == 3)
                {
                    old.PassWord = string.IsNullOrEmpty(model.PassWord) || model.PassWord == old.PassWord ? old.PassWord : MD5Helper.GetMD5(model.PassWord);
                }
                old.Tel = string.IsNullOrEmpty(model.Tel) ? old.Tel : model.Tel;
                old.Email = string.IsNullOrEmpty(model.Email) ? old.Email : model.Email;
                var oldroles = _efCore_RepositoryService.GetMany(new DirectSpecification<MngrRole>(x => !x.IsDeleted && x.MemberId == model.ID)).ToList();
                List<MngrRole> rolelist = new List<MngrRole>();
                Roles.ForEach(x =>
                {
                    if (!oldroles.Select(y => y.RoleId).Contains(x.RoleId))
                    {
                        //add
                        x.CreateTime = DateTime.Now;
                        x.ID = Guid.NewGuid().ToString();
                        x.MemberId = model.ID;
                        rolelist.Add(x);
                    }
                });
                var delroleid = oldroles.Where(x => !Roles.Select(y => y.RoleId).Contains(x.RoleId) && !x.IsDeleted).Select(x => x.ID).ToList();
                delroleid.ForEach(x =>
                {
                    _efCore_RepositoryService.LogicDelete(new DirectSpecification<MngrRole>(y => y.ID == x));
                });
                _efCore_RepositoryService.AddBatch(rolelist);
                _efCore_RepositoryService.Update(old, x => x.NickName, x => x.PassWord, x => x.State, x => x.CpnId, x => x.Tel, x => x.Email);
                data.ID = old.ID;
                data.NickName = old.NickName;
                data.PassWord = old.PassWord;
                data.State = old.State;
                _mngrLog_DomainService.AddMngrLog("修改用户", $"用户:{old.LoginName}被修改");
            }
            _efCore_RepositoryService.SaveChanges();
            return data;
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="deld"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public IEnumerable<string> DelManager(HttpRequest httpRequest, string uid)
        {
            IEnumerable<string> deld = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(httpRequest.Form["delds"]);
            if (deld.Contains(uid))
            {
                throw new UNException("不能包含当前用户,请重新选择！");
            }
            _efCore_RepositoryService.LogicDelete(new DirectSpecification<MngrBaseInfo>(y => deld.Contains(y.ID)));
            _efCore_RepositoryService.LogicDelete(new DirectSpecification<MngrRole>(y => deld.Contains(y.MemberId)));
            _efCore_RepositoryService.SaveChanges();
            var names = (_efCore_RepositoryService.GetMany(new DirectSpecification<MngrBaseInfo>(y => deld.Contains(y.ID)))
                    ).Select(x => x.LoginName);
            _mngrLog_DomainService.AddMngrLog("删除用户", $"用户:{string.Join(",", names)}被删除");

            return names;
        }

        public LoginUserDTO GetCaheUser()
        {
            return _mngrBaseInfo_RepositoryService.GetCaheUser();
        }

        #endregion
    }
}
